package com.zlw.main.audioeffects.view;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ValueAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Shader;
import android.graphics.Shader.TileMode;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.LinearInterpolator;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

//import com.android.music.MediaPlaybackActivity;
//import com.android.music.utils.ClickUtils;
//import com.android.music.utils.DisplayUtils;
import com.zlw.main.audioeffects.MainActivity;
import com.zlw.main.audioeffects.R;
import com.zlw.main.audioeffects.bean.LrcLine;
import com.zlw.main.audioeffects.utils.ClickUtils;
import com.zlw.main.audioeffects.utils.DisplayUtils;

import java.util.ArrayList;
import java.util.List;

public class LrcTextView extends android.support.v7.widget.AppCompatTextView {
    private String TAG = "LrcTextView";
    private float mHeight;
    private float mWidth;
    private Paint mCurrentPaint;
    private Paint mPaint;
    private Paint mHidingPaint;
//    private Paint mLinePaint;
    private float mTextHeight = 65;
    private float mMarginLeft = 0;
    private static final long ANIM_RUN_MAX_TIME = 500;
    private static final int WORD_MARGIN_LEFT = 20;
    private int mIndex = -1;
    private boolean mIsEdit = false;
    
    private List<LrcLine> mLyricLines = new ArrayList<LrcLine>();
    
    private float mBeginY = 0;
    private float mMoveDistance = 0;
    private float mAnimStepY = 0;
    private DragTextEvent mEvent = null;
//    private float mPaintHeight = 0;
    private boolean mIsMoving = false;
    private int mTextSize;
    private float mFontScale = 1;
    private boolean hasTime;
    private boolean mIsFirst=true;
    private GestureDetector mDetector;
    private boolean mIsHorizontalMoving = false;
    private float mIncrement = 0;
    //private float mHorizontalOffset = 0;
    private String mCurrentLrc;
    private MainActivity mActivity;
    private List<Integer> mPaintColors;
    RelativeLayout mLrcIdentification;
    TextView lrcTextView;
    public static final String CHANGE_SEEKBAR="lrctextviewchangeseekbar";
    public boolean mUpdateLrc=true;
    public static final int LRCMSG=1;
    public static final int LRCMSG2=2;
    
    private List<LrcString> mLrcStrings = new ArrayList<LrcString>();
    
    public void setIncrement(float f) {
        mIncrement = f;
    }
    
    public void setHasTime(boolean b) {
        hasTime = b;
    }
    
    public void setLyricLines(List<LrcLine> lines) {
        Log.i(TAG, "setLyricLines lines= " + lines);
        mLyricLines = lines;
        if (mLrcIdentification != null) {
            mLrcIdentification.setVisibility(View.INVISIBLE);
        }
        mIsFirst=true;
        initRealDrawsLrc();
        invalidate();
    }
    
    public void setLyricIndex(int index) {        
        if(mIndex != index && !mIsMoving) {
            mIndex = index;
            Log.i(TAG, "setLyricIndex mIndex= " + mIndex);
            if (mLyricLines != null && mLyricLines.get(mIndex) != null) {
                mCurrentLrc = mLyricLines.get(mIndex).getLrcStr();
                //Log.i(TAG, "setLyricIndex mCurrentLrc= " + mCurrentLrc);
            }
            clearAnimation();
            //Log.i(TAG, "setLyricIndex mMoveDistance= " + mMoveDistance);
            if(mMoveDistance > getStingsPosFromLrcPos(mIndex) * mTextHeight) {
               if (mUpdateLrc) {
                   mMoveDistance = getStingsPosFromLrcPos(mIndex - 1) * mTextHeight;  
               }  
               
                
            }
            Log.i(TAG, "mMoveDis " + mMoveDistance);
            //滑动过程中禁止更新歌词
            if(mUpdateLrc){
                startNewAnim();
            }
            mIsHorizontalMoving = false;
            //mHorizontalOffset = 0;
        }        
    }
    
    public String getCurrentLrc() {
        return mCurrentLrc;
    }

    public void resetCurrentLrc() {
        mCurrentLrc = null;
        mMoveDistance = 0;
    }
    
    public void setTextEvent(DragTextEvent it) {
        mEvent = it;
    }
    
    public void resetTextView() {
        mBeginY = 0;
        mMoveDistance = 0;
        mAnimStepY = 0;
        mIndex = -1;
    }
    
    public void pause() {
        clearAnimation();
        mMoveDistance += mAnimStepY;
        mAnimStepY = 0;        
    }
    
    public void setLrcState(boolean isEdit) {
        mIsEdit = isEdit;
    }
    
    public boolean getLrcState() {
        return mIsEdit;
    }
    
    public LrcTextView(Context context) {
        super(context);        
        mMarginLeft = DisplayUtils.dip2px(context, WORD_MARGIN_LEFT);
//        mTextSize = context.getResources().getInteger(R.integer.lrc_text_size);
        //mTextSize = DisplayUtils.sp2px(context, 16);
        //mTextHeight = DisplayUtils.dip2px(context, 20) + mTextSize;
          mTextSize = DisplayUtils.sp2px(context, 15);
          mTextHeight = DisplayUtils.dip2px(context, 14) + mTextSize;
        mDetector = new GestureDetector(context, onGestureListener);
        init();
    }

    public LrcTextView(Context context, AttributeSet attrs) {
        super(context, attrs);
        mMarginLeft = DisplayUtils.dip2px(context, WORD_MARGIN_LEFT);
//        mTextSize = context.getResources().getInteger(R.integer.lrc_text_size);
        //mTextSize = DisplayUtils.sp2px(context, 16);
        //mTextHeight = DisplayUtils.dip2px(context, 20) + mTextSize;
        mTextSize = DisplayUtils.sp2px(context, 15);
        mTextHeight = DisplayUtils.dip2px(context, 14) + mTextSize;
        mDetector = new GestureDetector(context, onGestureListener);
        init();
    }
    
    private void init() {        
        mCurrentPaint = new Paint();
        mCurrentPaint.setTextAlign(Paint.Align.LEFT);
        mCurrentPaint.setAntiAlias(true);
        //mCurrentPaint.setColor(0xccffffff);
        mCurrentPaint.setColor(0xfff44778);
        mCurrentPaint.setTextSize(mTextSize);
//        mCurrentPaint.setTypeface(Typeface.SERIF);

        mHidingPaint = new Paint();
        mHidingPaint.setTextAlign(Paint.Align.LEFT);
        mHidingPaint.setAntiAlias(true);
        //mHidingPaint.setColor(0x22ffffff);
        //mHidingPaint.setShader(shader);
        mHidingPaint.setTextSize(mTextSize);

        mPaint = new Paint();
        mPaint.setTextAlign(Paint.Align.LEFT);
        mPaint.setAntiAlias(true);
        mPaint.setColor(0x50ffffff);
        mPaint.setTextSize(mTextSize);
//        mPaint.setTypeface(Typeface.SERIF);
//        mPaintHeight = getFontRect(mPaint, "我").height();
        setPaintTextSize();
//        mLinePaint = new Paint();
//        mLinePaint.setColor(0x600080ff);
//        mLinePaint.setAntiAlias(true);
//        mLinePaint.setStrokeWidth(6);
        
//        initPaintColors();
    }

    private Shader getShader(boolean isUp, int beginY, int endY) {
        int color1 = 0x00ffffff;
        int color2 = 0x20ffffff;
        Shader shader;
        if (isUp) {
            shader = new LinearGradient(0, beginY,
                            0, endY, 
                            color1, 
                            color2,
                            TileMode.CLAMP);
        } else {
            shader = new LinearGradient(0, beginY,
                            0, endY, 
                            color2, 
                            color1,
                            TileMode.CLAMP);
        }

        return shader;
    }    
    private void initPaintColors() {
        mPaintColors = new ArrayList<Integer>();
        mPaintColors.add(0xfff44778);
        mPaintColors.add(0x99ffffff);
        mPaintColors.add(0x99ffffff);
        mPaintColors.add(0x66ffffff);
    }

    public void initActivity(Activity activity) {
        if(activity instanceof MainActivity)
            mActivity = (MainActivity) activity;
    }

    @Override
    protected void onDraw(Canvas canvas) {
        if(canvas == null || mLyricLines == null || mLyricLines.size() == 0) {
            Log.i(TAG, "onDraw return");
            return;
        }
        try {
            float tempY = mHeight / 2 - mMoveDistance - mAnimStepY;
           // Log.i(TAG, "mMove = " + mMoveDistance + ", index = " + mIndex);
           // Log.i(TAG, "mLrcStrings.size() = " + mLrcStrings.size());
            //drawText写字是已Y为基准往上写，drawline是以Y为基准往下画
            for(int i = 0; i < mLrcStrings.size(); i++) {                                            
                mMarginLeft = mWidth / 2 - mPaint.measureText(mLrcStrings.get(i).lrc_str) / 2;
                mMarginLeft = mMarginLeft > 0 ? mMarginLeft : 0;
                if (tempY > -8 && tempY < mTextHeight) {
                    Shader shader = getShader(true, 0, (int)mTextHeight);
                    mHidingPaint.setShader(shader);
                    canvas.drawText(mLrcStrings.get(i).lrc_str, mMarginLeft, tempY, mHidingPaint);
                } else if ((tempY < mHeight && (tempY+mTextHeight) > mHeight)
                    || (tempY > mHeight && (tempY-mTextHeight) < mHeight)) {
                    Shader shader = getShader(false, (int)(mHeight-mTextHeight), (int)mHeight);
                    mHidingPaint.setShader(shader);
                    canvas.drawText(mLrcStrings.get(i).lrc_str, mMarginLeft, tempY, mHidingPaint);
                } else {
                    canvas.drawText(mLrcStrings.get(i).lrc_str, mMarginLeft, tempY, getMyPaint(mLrcStrings.get(i).lrc_pos));
                }
                tempY += mTextHeight;                
            }
        } catch (Exception e) {
            Log.i(TAG, e.toString());
        }
                
    }
    
    long probablyTime;
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        Log.i(TAG, "onTouchEvent: " + event.getAction());
        mDetector.onTouchEvent(event);
        if(getLrcState()) {
            Log.i(TAG, "onTouchEvent: " + "Lrc is edit mode now!");
            return true;
//            return super.onTouchEvent(event);
        }

        try {
            switch(event.getAction()) {
                case MotionEvent.ACTION_MOVE: {
               //===========================================================================     
                   //利用滑动距离计算歌词位置对应时间，填充文本
                   int probablyIndex= Math.round(mMoveDistance/mTextHeight)+1;
                   if(probablyIndex<=0){
                       probablyIndex=0;
                   }
                   
                   if(probablyIndex>=mLyricLines.size()){
                       probablyIndex=mLyricLines.size()-1;
                   }
                   probablyTime = mLyricLines.get(probablyIndex).getPos()+(long)mIncrement;
                   StringBuilder lrcIdentificationTime = getLrcIdentificationTime(probablyIndex);
                   if (lrcTextView != null) {
                       lrcTextView.setText(lrcIdentificationTime);
                   }


             //================================================================================ 
                   if(mBeginY < 0) {
                       mBeginY = event.getRawY();                        
                   }                    
                   float tmpY = event.getRawY() - mBeginY;
                   if(!mIsMoving && Math.abs(tmpY) < 30) {
                       return true;
                   }
                   //mIsMoving = true;
                   mMoveDistance = computeMoveDistance(tmpY);
                   //Log.i(TAG, "touch move mMoveDistance= " + mMoveDistance);
             //===========================================================================     
                   //歌词指示条5秒后隐藏
                   Log.i(TAG,"mIsFirst="+mIsFirst);
                     if (hasTime) {
                         if (mLrcIdentification != null) {
                             mLrcIdentification.setVisibility(View.VISIBLE);
                         }

                    }else if (!hasTime&&mIsFirst) {
                        mIsFirst=false;
                        Toast.makeText(mActivity, R.string.playback_lrcIdentification,
                                Toast.LENGTH_SHORT).show();
                    }
                     mUpdateLrc=false;
                     Message message = Message.obtain();
                     message.what=LRCMSG;
                     lrcMessagesHandler.removeMessages(LRCMSG);
                     lrcMessagesHandler.sendMessageDelayed(message, 3000);
                     Message message2 = Message.obtain();
                     message2.what=LRCMSG2;
                     lrcMessagesHandler.removeMessages(LRCMSG2);
                     lrcMessagesHandler.sendMessageDelayed(message2, 3500);
             //================================================================================    
                 
                   mBeginY = event.getRawY();
                   invalidate();
                    return true;
                }
                case MotionEvent.ACTION_DOWN: {
              
                    //clearAnimation();
                    /*  if(hasTime) {
                        mMoveDistance = getStingsPosFromLrcPos(mIndex-1) * mTextHeight; 
                        //Log.i(TAG, "touch down mMoveDistance= " + mMoveDistance);
                    } */                   
                    mBeginY = event.getRawY();
                     // cancelEditMode();
                    return true;
                }
                case MotionEvent.ACTION_UP:
                    
                case MotionEvent.ACTION_CANCEL: {
                    mBeginY = -1;
                    if(!mIsMoving) {
                        return true;
                    }
                    mIsMoving = false;
                    int index = getLrcPosFromStringsPos((int) (mMoveDistance / mTextHeight));
                    index = (mMoveDistance % mTextHeight != 0) ? (index + 1) : index;
                    index = (index >= mLyricLines.size()) ? (mLyricLines.size() - 1) : index;
                    setLyricIndex(index);
                    break;
                }
                default:
                    break;
            }            
            return super.onTouchEvent(event);
        } catch (Exception e) {
            e.printStackTrace();
            Log.i(TAG, "onTouchEvent : " + e.toString());
            return super.onTouchEvent(event);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mWidth = w;
        mHeight = h;
    }
    
    
    private void startAnim() {        
        ValueAnimator animator = ValueAnimator.ofFloat(0, getMoveDis());
        animator.setDuration(getAnimRunTime());
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator value) {
                float tmp = (Float) value.getAnimatedValue();
                mAnimStepY = tmp;
                Log.i(TAG, "mMoveDistance = " + mMoveDistance + ", tmp = " + tmp);
                invalidate();
            }
        });
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                mMoveDistance += mAnimStepY;
                Log.i(TAG, "onAnimationEnd " + mMoveDistance);
                mAnimStepY = 0;
            }            
        });
        animator.start();
    }
    
    private long getAnimRunTime() {
        try {
            long time_cur = mLyricLines.get(mIndex).getPos();
            long time_next = mLyricLines.get(mIndex + 1).getPos();
            long time = time_next - time_cur;
            Log.i(TAG, "time = " + time + ", time_cur = " + time_cur + ", time_next = " + time_next);
            return time * 1000;
        } catch(Exception e) {
            return 0;
        }                
    }
    
    private Paint getMyPaint(int index) {
        if(index == mIndex) {
            return mCurrentPaint;
        } else {
            return mPaint;
        }
    }
    
    private Paint getMyPaintByY(float y) {
//        mPaint.setColor(mPaintColors.get(getLinePosWithMiddle(y)));
//        return mPaint;
        return isCurrentLine(y) ? mCurrentPaint : mPaint;
    }
    
    private boolean isCurrentLine(float y) {
        if(y < (mHeight / 2 + mTextHeight / 2) && y > (mHeight / 2 - mTextHeight / 2)) {
            return true;
        } 
        return false;
    }
    
    private int getLinePosWithMiddle(float y) {
        float min = mHeight / 2 - mTextHeight / 2;
        float max = mHeight / 2 + mTextHeight / 2;
        int pos = 3;
        if(y < max && y > min) {
            pos = 0;
        } else {
            for(int i = 0; i < 3; i++) {                
                if(((y < (min - mTextHeight * i)) && (y > (min - mTextHeight * (i + 1))))
                        || ((y > (max + mTextHeight * i)) && (y < (max + mTextHeight * (i + 1))))) {
                    pos = i + 1;
                    break;
                }
            }    
        }
        return pos;                    
    }
    
    private void showLrcHorizontalMoveAnim(int i, float y) {
        if(!isCurrentLine(y) || mLyricLines == null || mLyricLines.size() <= i || mIsHorizontalMoving) {
            return;
        }
        
        if(mIndex < 0 || mIndex >= mLyricLines.size() || i != mIndex) {
            return;
        }
        
        String str = mLyricLines.get(mIndex).getLrcStr();
        int width = DisplayUtils.getFontRect(mCurrentPaint, str).width(); 
        if(width <= (mWidth - mMarginLeft)) {
            return;
        }
        
        long begin = (long) ((mLyricLines.get(mIndex).getPos() + mIncrement)* 1000);
        long end = begin;
        if((mIndex + 1) < mLyricLines.size()) {
            end = (long) ((mLyricLines.get(mIndex + 1).getPos() + mIncrement)* 1000);
        }
        long offset = end - begin;
        if(offset <= 0) {
            return;
        }

        startLrcHorizontalMoveAnim(width, (int) (offset / 2));                        
    }
    
    private void startLrcHorizontalMoveAnim(int width, int duration) {
        AnimatorSet animatorSet = new AnimatorSet();
        ValueAnimator animator0 = ValueAnimator.ofFloat(0, width - mWidth + mMarginLeft);
        animator0.setDuration(duration);        
        ValueAnimator animator = ValueAnimator.ofFloat(0, width - mWidth + mMarginLeft);
        animator.setDuration(duration < 300 ? duration : 300);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator arg0) {
                //mHorizontalOffset = (Float) arg0.getAnimatedValue();                
                invalidate();
            }
        });
//        animator.addListener(new AnimatorListenerAdapter() {
//            @Override
//            public void onAnimationEnd(Animator animation) {
//                mHorizontalOffset = 0;
////                mIsHorizontalMoving = false;
//            }            
//        });
        mIsHorizontalMoving = true;
        animatorSet.play(animator).after(animator0);
        animatorSet.start();
    }
    
    private float getMoveDis(){
        float tmp = getStingsPosFromLrcPos(mIndex + 1) * mTextHeight - mMoveDistance;        
        return tmp;
    }
    
    private void startNewAnim() {
        ValueAnimator animator = ValueAnimator.ofFloat(0, getSingleLrcCountByLrcPos(mIndex - 1) * mTextHeight - mMoveDistance % mTextHeight);
        long time = getAnimRunTime();
        time = time > ANIM_RUN_MAX_TIME ? ANIM_RUN_MAX_TIME : time / 2;
        animator.setDuration(time);
        animator.setInterpolator(new LinearInterpolator());
        animator.addUpdateListener(new AnimatorUpdateListener() {
            @Override
            public void onAnimationUpdate(ValueAnimator value) {
                float tmp = (Float) value.getAnimatedValue();
                if(mMoveDistance > getStingsPosFromLrcPos(mIndex) * mTextHeight) {
                    mMoveDistance = getStingsPosFromLrcPos(mIndex - 1) * mTextHeight;    
                }
                //Log.i(TAG, "startnewanim mMoveDistance= " + mMoveDistance);
                //Log.i(TAG, "startnewanim index= " + mIndex);
                mAnimStepY = tmp;
                invalidate();
            }
        });
        animator.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
//                mMoveDistance += mTextHeight;
                mMoveDistance = getStingsPosFromLrcPos(mIndex) * mTextHeight;
                //Log.i(TAG, "onAnimationEnd " + mMoveDistance + ", mIndex " + mIndex + ",stepy="+mAnimStepY);
                mAnimStepY = 0;
                //设置下一行播放时间
                setLrcIdentificationTextView();
            }            
        });
        animator.start();
    }
    
    private float computeMoveDistance(float step) {        
        try {
            float max = (mLrcStrings.size() - 1) * mTextHeight;
            float tmp = mMoveDistance - step;
            if(tmp < 0) {
                tmp = 0;
            } else if(tmp > max) {
                tmp = max;
            }            
            return tmp;
        } catch (Exception e) {
            e.printStackTrace();
            Log.i(TAG, "computeMoveDistance : " + e.toString());
            return 0;
        }
    }
    
    private Rect getFontRect(Paint paint, String str) {
        if(paint == null) {
            return null;
        }
        
        Rect rect = new Rect();
        paint.getTextBounds(str, 0, str.length(), rect);
        Log.i(TAG, "" + rect);
        return rect;
    }
    
    private void cancelEditMode() {
        if(getLrcState()) {
            setLrcState(false);
            if(mEvent != null) {
                mEvent.changeEditMode(false);
            }    
        }        
    }
        
    public interface DragTextEvent {
        public void changeEditMode(boolean isEdit);
        public void searchLrc();
    }
    
    public void setLrcIdentificationEvent(RelativeLayout relation){
//        mLrcIdentification = relation;
//        lrcTextView = (TextView) mLrcIdentification.findViewById(R.id.lrc_iden_tv1);
//         RelativeLayout imageIdentification=(RelativeLayout) mLrcIdentification.findViewById(R.id.lrc_iden_im1);
//        imageIdentification.setOnClickListener(new LrcIdentificationListener());
        
    }
    
    class LrcIdentificationListener implements OnClickListener {

        @Override
        public void onClick(View arg0) {
            if (ClickUtils.isFastDoubleClick(1000)) {
                return;
            }
//            mActivity.updateSeekBar(probablyTime);
        }
        
        
    }
    
    
    
    public void setLrcIdentificationTextView(){
//        StringBuilder time = getLrcIdentificationTime(mIndex+1);
//        lrcTextView.setText(time);
    }

    private StringBuilder getLrcIdentificationTime(int index) {
        StringBuilder time =new StringBuilder();
        StringBuilder lastTime =new StringBuilder("--:--");
        long timeNext=0;
    
        try {
              
            timeNext = mLyricLines.get(index).getPos()+(long)mIncrement;
             //Log.i("====================",timeNext+"");
             long minute = timeNext/60;
                long second = timeNext%60;
                if(0<=second&&second<=9){
                    time.append(minute).append(":").append(0).append(second);    
                }else{
                    time.append(minute).append(":").append(second);
                } 
        } catch (Exception e) {
            e.printStackTrace();
            Log.i("====================","出错了"+"time=lastTime"+time);
            time=lastTime;
        }
        return time;
    }
    
    
    private OnGestureListener onGestureListener = new OnGestureListener() {
        
        @Override
        public boolean onSingleTapUp(MotionEvent arg0) {
            if(mLyricLines == null || mLyricLines.size() == 0 || !hasTime) {
                if (mLyricLines == null || mLyricLines.size() == 0) {
                    if(mEvent != null) {
                        mEvent.searchLrc();
                    }
                }
                return true;
            }
            mIsEdit = !mIsEdit;
            if(mEvent != null) {
                mEvent.changeEditMode(mIsEdit);
            }
            return true;
        }
        
        @Override
        public void onShowPress(MotionEvent arg0) {
        }
        
        @Override
        public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
                                float arg3) {
            return false;
        }
        
        @Override
        public void onLongPress(MotionEvent arg0) {
        }
        
        @Override
        public boolean onFling(MotionEvent eventold, MotionEvent eventnow, float velocityX,
                               float velocityY) {
            return false;
        }
        
        @Override
        public boolean onDown(MotionEvent arg0) {
            return false;
        }
    };
    
    @Override
    protected void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        mFontScale = newConfig.fontScale;
        Log.i("qinl", "mFontScale " + mFontScale);
        setPaintTextSize();
        invalidate();
    }
    
    private void setPaintTextSize() {
        try {
            mFontScale = (mFontScale <= 0) ? 1 : mFontScale;
            mCurrentPaint.setTextSize(mTextSize * mFontScale);
            mPaint.setTextSize(mTextSize * mFontScale);
            mHidingPaint.setTextSize(mTextSize * mFontScale);
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }
    
    private List<String> getLrcSplitLines(String lrc) {
        List<String> list = new ArrayList<String>();
        if(lrc == null) {
            return list;
        }
        
        String tmp = peelSuitableLineFromString(lrc, list);
        while(tmp != null && tmp.length() != 0) {
            tmp = peelSuitableLineFromString(tmp, list);
        }
        return list;
    }
    
    private float getStringWidth(String str) {
        if(mPaint == null || str == null) {
            return -1;
        }
    
        return mPaint.measureText(str);
    }
    
    private boolean isEnglishChar(char c) {
        if((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
            return true;
        }
        return false;
    }
    
    private String peelSuitableLineFromString(String str, List<String> list) {
        if(str == null || list == null) {
            return "";
        }
        float scale = mWidth / getStringWidth(str);
        if(scale >= 1) {
            list.add(str);
            return "";
        }
        
        int pos = (int) (scale * str.length());        
        
        while(getStringWidth(str.substring(0, pos)) > mWidth) {            
            pos--;
            if(pos == 0) {
                break;
            }
        }
        if (pos<0) {
            pos=0;
        }
        pos = getCurrentPos(str, pos);
        list.add(str.substring(0, pos));
        
        return str.substring(pos);
    }
    
    private int getCurrentPos(String str, int pos) {
        if(str == null) {
            return pos;
        }
        
        if(pos <= str.length() - 1) {
            char next = str.charAt(pos);
            if(isEnglishChar(next)) {
                while(isEnglishChar(str.charAt(pos - 1))) {
                    pos--;
                }
            }
        }        
        return pos;
    }
    
    private void initRealDrawsLrc() {
        if(mWidth == 0) {
            postDelayed(new Runnable() {
                @Override
                public void run() {
                    initRealDrawsLrc();
                }
            }, 300);
            return;
        }
        
        if(mLyricLines == null) {
            return;
        }
        mLrcStrings.clear();
        for(int i = 0; i < mLyricLines.size(); i++) {            
            List<String> list = getLrcSplitLines(mLyricLines.get(i).getLrcStr());
            for(int j = 0; list != null && j < list.size(); j++) {
                LrcString item = new LrcString();
                item.lrc_pos = i;
                item.lrc_str = list.get(j);
                mLrcStrings.add(item);                
            }            
        }
    }
    
    private int getStingsPosFromLrcPos(int index) {
        for(int i = 0; i < mLrcStrings.size(); i++) {
            if(index == mLrcStrings.get(i).lrc_pos) {
                return i;
            }
        }
        return 0;
    }
    
    private int getLrcPosFromStringsPos(int index) {
        return mLrcStrings.get(index).lrc_pos;
        
    }
    
    private int getSingleLrcCountByLrcPos(int index) {
        if(index < 0) {
            return 0;
        }
        int count = 0;
        for(int i = 0; i < mLrcStrings.size(); i++) {
            if(index == mLrcStrings.get(i).lrc_pos) {
                count++;
            }
        }
        return count;
    }
    
    private static class LrcString {
        public int lrc_pos;
        public String lrc_str;
    }
  
    
    Handler lrcMessagesHandler = new Handler(){
        
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            try {
                if(msg.what==LRCMSG){
                    if (mLrcIdentification != null) {
                        mLrcIdentification.setVisibility(View.INVISIBLE);
                    }

                }
                
                if(msg.what==LRCMSG2){    
                    mUpdateLrc=true;
                }
                
            } catch (Throwable e) {
                e.printStackTrace();
            }
            
        }
        
        
    };
    
}
